﻿// For security purpose, we encrypt password in the string
// It cannot be sent crypted to Mantis Web Service, but
// at least it will not appear decrypted in the parameters
// string

using System;
using System.Text;                  // For encoding
using System.IO;                    // For stream
using System.Security.Cryptography; // For encryption

namespace Common
{
    class Encryption
    {
        private PasswordDeriveBytes pdb = null;
        private Rijndael rijndael = null;

        public Encryption(String system_password)
        {
            pdb = new PasswordDeriveBytes(system_password, new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

            rijndael = Rijndael.Create();

            rijndael.Key = pdb.GetBytes(32);
            rijndael.IV = pdb.GetBytes(16);
        }

        public string Encrypt(String value)
        {
            byte[] plaintextBytes = (new UnicodeEncoding()).GetBytes(value);

            MemoryStream msEncrypt = new MemoryStream();
            CryptoStream csEncrypt = new CryptoStream(msEncrypt, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
            csEncrypt.Write(plaintextBytes, 0, plaintextBytes.Length);
            csEncrypt.Close();
            byte[] encryptedTextBytes = msEncrypt.ToArray();
            msEncrypt.Close();

            string result = string.Empty;

            foreach (var b in encryptedTextBytes)
            {
                result += b.ToString("x2");
            }

            return result;// (new UnicodeEncoding()).GetString(encryptedTextBytes);
        }

        public string Decrypt(String encrypted)
        {
            byte[] encryptedTextBytes = new byte[encrypted.Length / 2];

            for (int i = 0; i < encrypted.Length; i += 2)
            {
                if (!byte.TryParse(encrypted.Substring(i, 2), System.Globalization.NumberStyles.HexNumber, null, out encryptedTextBytes[i / 2]))
                    return null;
            }

            MemoryStream msDecrypt = new MemoryStream(encryptedTextBytes);
            CryptoStream csDecrypt = new CryptoStream(msDecrypt, rijndael.CreateDecryptor(), CryptoStreamMode.Read);
            byte[] decryptedTextBytes = new Byte[encryptedTextBytes.Length];
            csDecrypt.Read(decryptedTextBytes, 0, encryptedTextBytes.Length);
            csDecrypt.Close();
            msDecrypt.Close();

            return (new UnicodeEncoding()).GetString(decryptedTextBytes).TrimEnd('\0');
        }
    }
}
